using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using TreeView.Logic;
using TreeView.Graphic;
using System.Drawing.Drawing2D;
using System.Collections;
using System.Text.RegularExpressions;
using Logic.Sequential;
using System.IO;
using Data.FileManager;
using Data.Probabilities;
using Logic.IB;
using Logic.Agglomerative;
using System.Runtime.InteropServices;
using System.Threading;
using Data.DataTranslator;
namespace Gui
{
    public partial class Main : Form
    {
        private RadialTree originalTree;
        private ProbabilityData probData;

        public Main()
        {
            InitializeComponent();
        }

        /// <summary>
        /// The run botton of the agglomerative algorithm
        /// </summary>
        /// 
        private void button1_Click(object sender, EventArgs e)
        {
            ArrayList a=null;
            progressBar1.Value = 0;
            kDimMap.aggProgBar = 0;
            AgglomerativeData dataHold = new AgglomerativeData(probData);
            Agglomerative t = new Agglomerative(dataHold, probData);
            int mergType = Cbox_MergFunc.SelectedIndex+1;
            int numOfCluster = (int)nud_AggNumOfCluster.Value;
            Thread AggThread = new Thread(delegate()
            {
                a = t.runAgglomerative(mergType, numOfCluster);
            });
            AggThread.Start();
            while (AggThread.IsAlive)
            {
                progressBar1.Value = (int)kDimMap.aggProgBar;
            }
            
            // ArrayList a = t.runAgglomerative(mergType, numOfCluster,progressBar1);
            double spreadAngle = (Double.Parse(txtInitialSprdAngl.Text)) / 180;
            if (spreadAngle > 2)
                spreadAngle = 2;
            originalTree = new RadialTree(a, 2);
            treeView.EnableResultView("360",originalTree);
        }

        private void txt_PartitionNum_Enter(object sender, EventArgs e)
        {
            this.txt_PartitionNum.BackColor = Color.Aqua;
        }

        private void txt_PartitionNum_Validating(object sender, CancelEventArgs e)
        {
            string errorMsg=null;
            bool problem = false;
            if (this.txt_PartitionNum.Text.Length != 0)
            {
                if (!Validate_isOneNumber(this.txt_PartitionNum.Text))
                {
                    problem = true;
                    errorMsg = errorMsg + System.Environment.NewLine + "you can't enter more than one number";
                }
                if (!Validate_isPositiveNumber(this.txt_PartitionNum.Text))
                {
                    problem = true;
                    errorMsg = errorMsg + System.Environment.NewLine + "you can't enter more than one number";
                }
                if (problem)
                {
                    e.Cancel = true;
                    this.txt_PartitionNum.Select(0, this.txt_PartitionNum.Text.Length);
                    this.numberOfPartionsErrorProvider.SetError(this.txt_PartitionNum, errorMsg);
                }
            }
        }

        private bool Validate_isOneNumber(string text)
        {
            Regex isNumberReg = new Regex("[0-9]+");
            MatchCollection m = isNumberReg.Matches(text);
            if (m.Count != 1)
                return false;
            return true;
        }
        private bool Validate_isPositiveNumber(string text)
        {
            Regex isNumberReg = new Regex("[-,+]+[0-9]+");
            MatchCollection m = isNumberReg.Matches(text);
            if (m.Count == 1)
            {
                if (Int32.Parse(m[0].Value) < 0)
                    return false;
            }
            return true;
        }

        private void txt_PartitionNum_Validated(object sender, EventArgs e)
        {
            this.numberOfPartionsErrorProvider.SetError(this.txt_PartitionNum, "");
            this.txt_PartitionNum.BackColor = Color.White;
        }

        private void btn_RunSeq_Click(object sender, EventArgs e)
        {
            int n = Int32.Parse(this.txt_PartitionNum.Text);
            int k = Int32.Parse(this.txt_NumberOfClusters.Text);
            int maxL = Int32.Parse(this.txt_ReplacmentsNum.Text);
            double epsilon = Double.Parse(this.txt_InfoThreshhold.Text);
            //Setting a new Sequential class and running it
            Sequential seq = new Sequential(k, maxL, n, epsilon, this.probData);
            seq.runSequential();
            Cell[] bestPartion = seq.BestPartition;
            //Setting the parameters values in the gui
            sequentialResults1.numberOfIterations = this.txt_PartitionNum.Text;
            sequentialResults1.numOfClusters = this.txt_NumberOfClusters.Text;
            sequentialResults1.maxL = this.txt_ReplacmentsNum.Text;
            sequentialResults1.epsilon = this.txt_InfoThreshhold.Text;
            sequentialResults1.InitializeDataToShow(bestPartion, k);
            if (this.MainTabs.Controls.Contains(this.SeqResTab))
                this.MainTabs.Controls.Remove(this.SeqResTab);
            this.MainTabs.Controls.Add(this.SeqResTab);
        }

        private void button1_Click_1(object sender, EventArgs e)
        {
            double t1=System.Environment.TickCount;
            this.button1.Enabled = false;
            FileHandler fh = FileHandler.Instance;
            StreamReader sReader = fh.openFileForReading("<Data>");
            this.probData = new ProbabilityData(sReader);
            double t2 = System.Environment.TickCount;
            System.Console.Beep(1000, 100);
            t2 = t1-t2;
            MessageBox.Show("Time for creating probability data is: " + t2.ToString());
            t1 = System.Environment.TickCount;
            StreamReader sReaderPropertiesCodes = fh.ValidateFile("<PropertiesData>", FileHandler.WorkingDirectory + "PropertiesData.dat");
            StreamReader sReaderPropertiesNames = fh.ValidateFile("<PropertiesNames>", FileHandler.WorkingDirectory + "PropertiesNames.dat");
            StreamReader sReaderGenomesNames = fh.ValidateFile("<GenomesNames>", FileHandler.WorkingDirectory + "GenomeNames.dat");
            Data.DataTranslator.kDimMap kdm = new Data.DataTranslator.kDimMap(sReaderPropertiesCodes, sReaderPropertiesNames, sReaderGenomesNames);
            t2 = System.Environment.TickCount;
            System.Console.Beep(1000, 100);
            t2 = t1 - t2;
            MessageBox.Show("Time for creating data translation is: " + t2.ToString());
            t1 = System.Environment.TickCount;
            DistanceFunction df = new DistanceFunction(probData);
            t2 = System.Environment.TickCount;
            System.Console.Beep(1000, 100);
            t2 = t1 - t2;
            MessageBox.Show("Time for creating distance matrix is: " + t2.ToString());
        }

        private void rbt_Agglomerative_CheckedChanged(object sender, EventArgs e)
        {
            group_Agglomerative.Enabled = true;
            group_Sequential.Enabled = false;
            group_Pam.Enabled = false;
        }

        private void rbt_sequential_CheckedChanged(object sender, EventArgs e)
        {
            group_Agglomerative.Enabled = false;
            group_Sequential.Enabled = true;
            group_Pam.Enabled = false;
        }

        private void rbt_Pam_CheckedChanged(object sender, EventArgs e)
        {
            group_Agglomerative.Enabled = false;
            group_Sequential.Enabled = false;
            group_Pam.Enabled = true;
        }

        private void radio_AggForSeq_CheckedChanged(object sender, EventArgs e)
        {
            group_Agglomerative.Enabled = true;
            group_Sequential.Enabled = true;
            group_Pam.Enabled = false;
        }

        private void WlcmTab_Click(object sender, EventArgs e)
        {

        }

        private void button2_Click(object sender, EventArgs e)
        {
            DistanceFunction df = new DistanceFunction(probData);
            ArrayList dgg = df.getMatrixInArrayList();
        }
    }
}